#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

#define SizeOfPage 100
#define SizeOfBlock 128
#define M 4  // 内存最多容纳的页面数

// 页表信息结构体
struct PageInfo {
    bool flag;      // 页标志，1表示该页在内存，0表示该页不在内存
    long block;     // 内存块号
    long disk;      // 页在磁盘上的位置
    bool dirty;     // 修改标志，1表示已修改
} pagelist[SizeOfPage];

// 全局变量
long po;            // 队列指针，表示当前需要被替换的页面
long P[M];          // 内存页面队列

// 分页式存储管理初始化
void init_paging() {
    memset(pagelist, 0, sizeof(pagelist));
    pagelist[0] = {true, 5, 011, false};
    pagelist[1] = {true, 8, 012, false};
    pagelist[2] = {true, 9, 013, false};
    pagelist[3] = {true, 1, 021, false};

    P[0] = 0;
    P[1] = 1;
    P[2] = 2;
    P[3] = 3;
    po = 0;

    cout << "分页式存储管理初始化完成。\n";
}

// 模拟分页式存储管理中的地址转换和缺页中断
void simulate_paging() {
    long p, q;
    char command[128];
    bool stop = false;

    while (!stop) {
        cout << "请输入指令的页号和单元号（输入 'exit' 退出）：\n";
        if (scanf("%ld%ld", &p, &q) != 2) {
            cin >> command;
            if (strcmp(command, "exit") == 0) {
                stop = true;
            } else {
                cout << "输入无效，请重新输入！\n";
            }
        } else {
            if (pagelist[p].flag) {
                cout << "绝对地址 = " << pagelist[p].block * SizeOfBlock + q << "\n";
            } else {
                cout << "缺页中断，页号 = " << p << "\n";
            }
        }
    }
}

// FIFO 页面调度算法初始化
void init_fifo() {
    init_paging();
    cout << "FIFO 页面调度算法初始化完成。\n";
}

// 模拟 FIFO 页面调度算法
void simulate_fifo() {
    long p, q;
    char command[128];
    bool stop = false;

    while (!stop) {
        cout << "请输入指令的页号和单元号（输入 'exit' 退出）：\n";
        if (scanf("%ld%ld", &p, &q) != 2) {
            cin >> command;
            if (strcmp(command, "exit") == 0) {
                stop = true;
            } else {
                cout << "输入无效，请重新输入！\n";
            }
        } else {
            if (pagelist[p].flag) {
                cout << "绝对地址 = " << pagelist[p].block * SizeOfBlock + q << "\n";
            } else {
                cout << "缺页中断，置换页面：\n";

                if (pagelist[P[po]].dirty) {
                    cout << "页面 " << P[po] << " 被修改，写回磁盘。\n";
                }

                cout << "页面 " << P[po] << " 被置换出内存。\n";
                pagelist[P[po]].flag = false;

                pagelist[p].block = pagelist[P[po]].block;
                pagelist[p].flag = true;
                P[po] = p;

                po = (po + 1) % M;
                cout << "页面 " << p << " 被调入内存。\n";
            }
        }
    }

    cout << "当前内存中的页面队列：\n";
    for (int i = 0; i < M; i++) {
        cout << "P[" << i << "] = " << P[i] << "\n";
    }
}

// 菜单选择
void select_option() {
    long option;
    char command[128];

    while (true) {
        cout << "\n请选择操作：\n1. 分页式存储管理\n2. FIFO 页面调度算法\n输入 'exit' 退出：\n";
        if (scanf("%ld", &option) != 1) {
            cin >> command;
            if (strcmp(command, "exit") == 0) {
                break;
            } else {
                cout << "输入无效，请重新选择！\n";
            }
        } else {
            if (option == 1) {
                init_paging();
                simulate_paging();
            } else if (option == 2) {
                init_fifo();
                simulate_fifo();
            } else {
                cout << "无效选项，请重新选择！\n";
            }
        }
    }
}

// 主函数
int main() {
    select_option();
    return 0;
}
